\documentclass[a4paper]{article}
\usepackage[dutch]{babel}
\usepackage[utf8x]{inputenc}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{fancyvrb}
\usepackage[all]{hypcap}

\newcommand{\HRule}{\rule{\linewidth}{0.5mm}}


\begin{document}
\input{title.tex}
\tableofcontents
\newpage

\section{Inleiding}
Het doel dit semester is om een licht gewijzigde versie van het spel Pac-man te kunnen spelen. Hiervoor heeft elk team een LegoMindstorms-robot ter beschikking die de rol van de ghosts in het spel zullen vervullen.
De bedoeling is dat er vier teams zijn die hun robots laten samenwerken om zo Pac-man in te sluiten en het spel te winnen.\\
De robots kunnen uitgerust worden met een licht-, ultrasone- en infraroodsensor om te navigeren door het doolhof.
Tijdens het spel zal Pac-man infrarood licht in alle richtingen uitzenden.\\
Om deze opdracht tot een goed einde te kunnen brengen moeten de teams met elkaar kunnen samenwerken via communicatie op basis van een overeengekomen protocol.
Een beperking aan deze communicatie is de voorwaarde dat alle Ghosts evenwaardig zijn.  Er kan dus geen master-slave relatie bestaan tussen de verschillende Ghosts.\\
Van elk team zal er \'e\'en lid deel uitmaken van een scheidsrechterscommissie.
Deze commissie doet dienst als overlegorgaan om belangrijke afspraken (zoals het communicatie-protocol) eenduidig vast te leggen tussen de verschillende teams.
Voor ons team is Maarten Christiaen de afgevaardigde. \\
Doorheen het semester worden er drie demo's georganiseerd, om de vordering van de studenten na te gaan. Het verslag volgt dezelfde opbouw.\\
Eerst wordt de probleemstelling uitgebreid omschreven, daarna volgt de beschrijving van de scheidsrechterscommissie en zijn beslissingen.
In de sectie over de fysieke Robot wordt de bouw van de robot en de nauwkeurigheid van de sensoren omschreven. Vervolgens komt de structuur van de software aan bod.
Ook worden nog de strategie, het gedrag van de robot, de voorstelling van de spelwereld en het simuleren van sensoren en motoren besproken.

\section{Probleemstelling}
\subsection{Demo 1}
Demo 1 heeft als doelstelling om een onbekend doolhof te verkennen en Pac-man, die stilstaat, te lokaliseren in het doolhof.\\
Een tweede deel van de opdracht is het schrijven van een simulator, die toelaat virtuele robots aan te maken die zich gedragen zoals een echte robot.
De simulator moet op basis van een gegeven doolhof de waarden kunnen simuleren die de sensoren van een echte robot zouden registreren (zonder rekening te houden met eventueel incorrecte waarden van een fysieke sensor).
Ook moet de simulator het rijden van de robots kunnen simuleren. \\
Het derde deel van de demo bestaat uit het maken van een grafische interface waarop te zien is welk deel van het doolhof elke robot kent, wat de sensoren van elke robot registreren en welke beslissingen de robots maken.
De evaluatie van deze demo zal gebeuren met behulp van drie virtuele robots en 1 echte robot.
Om het doolhof zo effici\"ent mogelijk te doorzoeken, zullen de vier robots informatie moeten uitwisselen en kunnen samenwerken.
Het protocol dat door de scheidsrechterscommissie is vastgelegd, bepaalt de communicatie tussen de verschillende robots.  
\subsection{Demo 2}
De additionele doelstelling voor deze demo, ten opzichte van demo 1, is het samen rijden met andere teams en het insluiten van een stilstaande pacman.
Vier fysieke robots moeten het doolhof volledig verkennen en een stilstaande pac-man kunnen insluiten.
De gegevens die elke robot gebruikt moeten kunnen doorgestuurd worden via het pakket \emph{RabbitMQ} op basis van het afgesproken protocol.  
\subsection{Demo 3}
De toevoeging bij deze demo is dat vanaf nu Pac-man kan rondrijden.  Het doel is dus dat de robots Pac-man lokaliseren en hem vastzetten door samen te werken zoals in de vorige demo, maar nu met de extra uitdaging dat Pac-man niet meer op \'e\'en plaats zal blijven. Om dit tot een goed einde te brengen zal er
een samenwerkingsstrategie moeten opgesteld worden zodat de robots samen Pac-man vastzetten zonder in elkaars weg te rijden.\\
De virtuele robots moeten nu ook kunnen omgaan met onzekere informatie. Hun sensoren en motoren moeten dus realistische afwijkingen vertonen.

\section{Scheidsrechterscommissie}
\subsection{Demo 1}
De scheidsrechterscommissie bestaat uit \'{e}\'{e}n lid van elk team en is verantwoordelijk voor het nemen van belangrijke beslissingen omtrent het verloop van het spel en het vastleggen van de algemene regels.\\
Een belangrijke taak hierbij is het opstellen van een communicatieprotocol.
Dit is nodig om de communicatie tussen de verschillende robots in goede banen te leiden.
De belangrijkste gevolgen van dit protocol en de regels die hiermee gepaard gaan, zijn de volgende:
\begin{itemize}
    \item     als een Ghost van sector verandert, moet hij zijn nieuwe locatie doorsturen.
    \item     een Ghost moet informatie die hij verzameld heeft over de grenzen van een sector doorsturen.
    \item     een gevonden barcode moet ook doorgestuurd worden. Hierbij moet informatie gegeven worden over de locatie van de sector waarop, en de richting waarin de barcode ligt.
    \item     een Ghost kan ook het pad dat hij van plan is te rijden doorsturen. De robot wordt dan wel geacht zich aan dit pad te houden.
\end{itemize}
Voor meer gedetailleerde informatie en het eigenlijke protocol verwijzen we naar het document \emph{Ghost Protocol Versie 1.0} op Toledo.\\
Daarnaast werd er in de commissie ook afgesproken dat de vier Ghosts elk in een hoek van het speelveld beginnen (met een willekeurige ori\"entatie).
Als het doolhof niet toelaat de robot in een hoek te plaatsen wordt deze zo dicht mogelijk bij de hoek geplaatst.
Een laatste beslissing van de commissie legt het bestandsformaat van een doorgestuurde maze vast. Het maze protocol is sterk gebaseerd op het Ghost protocol.
Hierdoor kan de code die verantwoordelijk is voor de communicatie tussen robots herbruikt worden.

\subsection{Demo 2}
De belangrijkste beslissing van de commissie voor demo 2 was het vastleggen van de doelstellingen voor deze demo.
Er is voor gekozen om weinig nieuwe dingen te introduceren ten opzichte van de eerste demo.
Deze beslissing kwam er omdat de resultaten van demo 1 niet goed waren.\\
Verder is er ook nog een kleine aanpassing aan het Ghost Protocol doorgevoerd: het commando \emph{BARCODE} werd veranderd naar \emph{BARCODEAT}.
Dit werd beslist omdat er bij het vorige commando fouten konden gebeuren in verband met het linken van een barcode aan een positie.
\subsection{Demo 3}
Ook in deze demo zijn er enkele aanpassingen gedaan aan het Ghost Protocol. Deze aanpassingen hebben vooral als doel om het samenwerken met de verschillende teams te vereenvoudigen.
De belangrijkste verandering is het toevoegen van een procedure om een gecrashte ghost opnieuw op te nemen in het spel.
De aanpassingen zijn samengevat in een nieuw document \emph{Ghost Protocol versie 2.2} op Toledo.

\section{Fysieke Robot}
\label{sec: fysiekeRobot}
Het design van de robot is aangepast in vergelijking met het vorige semester.
Dit komt vooral door de kleinere sectoren, maar ook door het feit dat de robot enkel nog op vlakke stukken moet kunnen rijden.
Het ontwerp is bijgevolg een stuk eenvoudiger geworden.\\
\subsection{Demo 1}
De belangrijkste voorwaarden waaraan het design moet voldoen zijn de volgende:
\begin{itemize}
\item De robot moet compact zijn, aangezien hij in staat moet zijn om te manoeuvreren op sectoren van $40cm*40cm$.
\item De licht-, ultrasone- en infraroodsensor moeten zo gemonteerd worden dat ze elkaar niet storen.    
\item De robot moet stabiel blijven. Dit wordt bekomen door het zwaartepunt centraal te houden.
\end{itemize}
Er is gekozen om de ultrasone sensor wendbaar te maken zodat deze de volledige omgeving rond de robot kan registreren zonder dat de robot zelf moet draaien.\\
De licht- en ultrasone sensor zijn vorig semester uitgebreid getest geweest (voor de resultaten verwijzen we naar het eindverslag van vorig semester).\\
De infraroodsensor is bij het begin van dit semester getest en de resultaten hiervan zijn te vinden in sectie \ref{sec: testIR}.

\subsection{Demo 2}
Voor deze demo zijn er druksensoren vooraan de robot toegevoegd om te kunnen registreren of de robot tegen een muur rijdt.
Dit blijkt een effectieve manier te zijn om de muren voor de robot te detecteren.
Een bijkomend voordeel is dat de robot zich ook terug recht duwt wanneer hij tegen een muur rijdt.

\subsection{Demo 3}
Tijdens demo 2 kwam een design flaw in de bouw van de robot naar voren: botsen tegen andere robots resulteerde niet in de beste manier van samenwerken.
Bijgevolg zijn de druksensoren en bijhorende botstactiek verwijderd.
In de plaats daarvan is de ultrasone sensor meer naar voren en lager geplaatst om zo nauwkeuriger muren en andere robots te kunnen detecteren.
Om deze sensor zo te kunnen plaatsen is ook de positie van de brick verandert. De brick staat nu schuin omhoog.
Door dit nieuwe design kan de ultrasone sensor echter niet meer naar achter kijken. Deze nieuwe beperking werd dan ook doorgevoerd in de code.

\begin{figure}[ht]
\centering
\includegraphics[width=0.8\linewidth]{robot.jpg}
\caption{Design van de robot.}
\label{fig:robot}
\end{figure}



\section{Softwareontwerp}
\label{sec: softwareontwerp}
\subsection{Demo 1 en 2}
\subsubsection{Overzicht}
Voor de eerste twee demo's waren de klassen anders gestructureerd dan voor de finale demo. Ter volledigheid volgt nu een bespreking van het toenmalige ontwerp. \\
Een klassendiagram is te vinden in figuur \ref{fig: pacmanOud}. De abstracte superklasse \emph{Robot} heeft twee subklassen, \emph{Ghost} en \emph{Pacman}\footnote{Bij het vermelden van een klasse zal de naam \emph{schuin} gedrukt worden. Anders wordt de naam gewoon vermeld.}.
Er wordt geen direct onderscheid gemaakt tussen de voorstelling van een virtuele en een echte ghost. Als er voor een bepaalde methode dit onderscheid toch gemaakt moet worden wordt gecheckt of de \emph{Ghost} een \emph{Communicator} heeft.
Deze zorgt namelijk voor de Bluetoothverbinding met de brick en is niet nodig voor een virtuele ghost.
Het enige andere verschil is welk type sensoren de ghost heeft. Een virtuele gebruikt in zijn virtuele sensoren de \emph{Simulator} om waarden te simuleren.
Een echte ghost gebruikt in zijn sensoren een \emph{Communicator} om via Bluetooth de sensorwaarden op te vragen.
\\
Deze manier van werken is verre van optimaal. Door geen onderscheid te maken tussen gesimuleerde en echte ghosts daalt de cohesie\footnote{Cohesie is een maat voor hoe sterk de verschillende verantwoordelijkheden van een softwaremodule verwant zijn.} van de \emph{Ghost}klasse enorm.
Het toevoegen van nieuwe functionaliteit wordt een hele uitdaging omdat er steeds moet gelet worden op de subtiele verschillen tussen virtuele en echte ghosts.
Deze aanpak werkte dus wel nog in het begin van het semester maar naarmate er meer functionaliteit werd toegevoegd bleek deze onhoudbaar.
Na de tweede demo werd er van nul een nieuw ontwerp uitgedacht.

\begin{figure}[ht]
\centering
\includegraphics[width=0.8\linewidth]{pacmanOud.png}
\caption{Vereenvoudigde klassenstructuur van het softwareontwerp voor demo 1 en 2}
\label{fig: pacmanOud}
\end{figure}

\subsubsection{protocol}
\label{sec: oudeProtocol}
Het protocol zoals vastgelegd in \emph{Ghost Protocol Versie 1.0} werd met behulp van verschillende klassen ge\"implementeerd.
In \emph{Game} liep een \emph{TimerTask} die om de 100 ms de queue van boodschappen bekijkt en verwerkt.
Het verwerken van een ontvangen boodschap gebeurde door een \emph{CommandParser}.
Deze deelt de string op in verschillende delen en afhankelijk van het commando wordt de correcte methode opgeroepen in Game.
Indien Ghost-specifieke informatie moet veranderen verwijst \emph{Game} door naar \emph{Ghost}.
Een schematische voorstelling is te vinden in figuur \ref{fig:protocolDiagram}.
\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{protocolDiagramOud.png}
\caption{Verwerking van een protocolboodschap (oude manier)}
\label{fig:protocolDiagram}
\end{figure}
Door de verwerking van alle boodschappen in \emph{Game} te laten gebeuren daalde de cohesie van die klasse en dus werd besloten deze functionaliteit een eigen klasse te geven.
Dezelfde redenering geld voor de klasse \emph{Ghost}. Meer informatie over de nieuwe structuur is te vinden in \ref{sec: protocol}

\subsection{Demo 3}
\subsubsection{Overzicht}
De structuur van ons ontwerp bestaat uit zeven packages: \emph{robots}, \emph{sensors}, \emph{pacman}, \emph{gui}, \emph{simulation}, \emph{maze} en \emph{bluetoothCommunication}.
De eerste drie zijn de belangrijkste, daarin zitten de grootste delen functionaliteit verwerkt. Een packagediagram is te vinden in figuur \ref{fig: packageDiagram}.

\begin{figure}[!h]
\centering
\includegraphics[width=\linewidth]{PackageDiagram.png}
\caption{Overzicht van de verschillende packages en de onderlinge verbanden}
\label{fig: packageDiagram}
\end{figure}

\emph{Robot} is natuurlijk het centrale pakket aangezien alles draait om het besturen van een ghost. Het gedrag van de ghosts staat beschreven in de klassen van \emph{robots.behaviour}.
Voor het analyseren van sectoren en barcodes bestaan klassen in \emph{robots.analyser}. De methodes die gebruikt worden om de robot in het midden van een sector en parallel aan de muur te plaatsen, staan in \emph{robots.correction}.
Aangezien de ghosts aangestuurd worden door een \emph{Pilot} en deze beschouwd worden als een sensor (zie \ref{sec: pilot}) is er ook een link tussen \emph{robots.correction} en \emph{sensors}.
Virtuele sensoren worden gesimuleerd met behulp van methoden uit \emph{simulation}.\\
Ghosts moeten ook boodschappen kunnen verzenden en ontvangen en daarvoor bestaan de klassen in \emph{pacman.protocol}.
De  afgesproken  protocollen (Ghost en Maze, beide te vinden op Toledo) zijn eigen aan een spelletje Pac-man en niet aan de robots, vandaar de plaatsing.\\
Het \emph{pacman}package zelf bevat onder andere de \emph{Game} die de ghosts van alle spelers bijhoudt. Zo'n \emph{Game} moet ook protocolberichten verwerken en heeft daarvoor een klasse uit het protocol subpakket nodig.
De \emph{gui} heeft informatie van een \emph{Game} nodig om een correcte weergave te maken. Bij een volledig gesimuleerd spel gebruikt de gui ook informatie uit de \emph{Simulator} om de precieze locatie van alle robots te tonen.

% In verslag stond er iets over het niet aanvaard worden van een compleet klassendiagram
% Een volledig klassendiagram is te vinden in figuur \ref{fig: compleetKlassendiagram}.
%
% \begin{figure}[ht]
% \centering
% \includegraphics[width=\linewidth]{klassendiagramPacman.png}
% \caption{Uitgebreide klassenstructuur voor de verschillende soorten robots en sensoren}
% \label{fig: compleetKlassendiagram}
% \end{figure}

\subsubsection{robots}
In deze package worden de verschillende soorten robots bijgehouden. Een overzicht van de verschillende soorten robots en hoe ze zich onderling verhouden is te zien in figuur \ref{fig: robotsDiagram}.

\begin{figure}[ht]
\centering
\includegraphics[width=0.75\linewidth]{RobotKlassenStructuur.png}
\caption{Vereenvoudigde klassenstructuur voor de verschillende soorten robots}
\label{fig: robotsDiagram}
\end{figure}

Naar aanleiding van de vele problemen die het ontwerp van de eerste twee demo's veroorzaakte, is er een grote refactoring gebeurd om het volledige softwareontwerp gebruiksvriendelijker te maken.
De grootste verwezenlijking was de opsplitsing van \emph{Ghost} in \emph{OwnGhosts}, \emph{RealGhosts} en \emph{VirtualGhosts}. Helemaal bovenaan staat de abstracte superklasse \emph{Robot}.
Deze houdt enkel een co\"ordinaat bij. De reden hiervoor is dat de locatie van \emph{Pac-man} nooit bekend is op centimeterniveau. Hetzelfde geldt voor de locatie van andere ghosts.
Omdat de ghosts van medespelers slechts een deel van de informatie nodig hebben die een eigen ghost heeft, werd niet direct het onderscheid gemaakt tussen \emph{VirtualGhost} en \emph{RealGhost}
maar werd \emph{OwnGhost} nog toegevoegd. Deze abstracte klasse houdt alle informatie bij die eigen ghosts hebben zoals een locatie op centimeterniveau, een \emph{sectorAnalyser}, \ldots \\
Een belangrijk verschil tussen een \emph{VirtualGhost} en \emph{RealGhost} is de manier waarop deze bestuurd worden. De virtuele en echte ghost hebben respectievelijk een \emph{RealPilot} en \emph{VirtualPilot}.
Meer uitleg hierover is te vinden in sectie \ref{sec: pilot}.
Verder gebruiken \emph{VirtualGhost} en \emph{RealGhost} ook andere types sensoren. Daarover meer in het volgende deel \ref{sec: sensors}.

\subsubsection{sensoren}
\label{sec: sensors}
Om de cohesie van de sensorklassen te verhogen is de structuur van het sensorspackage licht aangepast.
De bestaande interfaces blijven bestaan maar de abstracte klasse \emph{Sensor} wordt onderverdeeld in abstracte \emph{VirtualSensors} en \emph{RealSensors}.
Deze hebben respectievelijk een \emph{Simulator} (met bijhorende \emph{Randomizer} voor realistische foutensimulatie) en \emph{Communicator} om de meetwaarden van de verschilllende sensoren te simuleren of op te vragen.
Voor een klassendiagram, zie figuur \ref{fig: sensorDiagram}.
In vergelijking met de vorige demo's is de code voor het simuleren van de sensorwaarden verplaatst van de \emph{Simulator} naar de sensorklassen zelf.
Dit verlaagt de koppeling\footnote{Een softwaresysteem heeft een lage koppeling als elk onderdeel weinig tot geen kennis heeft van de andere.} tussen de sensoren en de \emph{Simulator} en verhoogt ook de cohesie van beide. \\
Nog een verandering in vergelijking met de vorige twee demo's is de toevoeging van \emph{Pilots}. Deze stellen abstracties van de motoren voor.
Technisch gezien zijn dit dus geen sensoren maar ze passen wel goed in de idee van de splitsing van virtuele en echte ghosts.
Een \emph{Pilot} voorziet de methoden voor het rechtdoor rijden en roteren van de robot. Meer info over de \emph{Pilots} is te vinden in sectie \ref{sec: pilot}.

\begin{figure}[ht]
\centering
\includegraphics[width=0.8\linewidth]{SensorDiagram.png}
\caption{Klassenstructuur van de verschillende soorten sensoren}
\label{fig: sensorDiagram}
\end{figure}


\subsubsection{simulation}
Dit pakket bevat alle klassen die noodzakelijk zijn voor het simuleren van een spelletje Pac-man. De centrale klasse is de \emph{Simulator}. Deze houdt de echte locaties en rotaties van de ghosts bij.
Een \emph{OwnGhost} houdt ook een locatie en rotatie bij maar deze weerspiegelen niet per se de exacte waarden. De opgeslagen locaties worden onder andere gebruikt voor het vermijden van botsingen met andere \emph{Ghosts}.
In dit pakket zitten ook klassen zoals \emph{ColorMap} en \emph{RayCaster} die helpen bij het simuleren van respectievelijk de lichtsensor en de ultrasone-en infraroodsensor.

\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{simulatorKlassendiagram.png}
\caption{Klassendiagram van de simulator}
\label{fig:klassendiagramSimulator}
\end{figure}

\subsubsection{maze}
In het mazepackage zitten alle klassen die helpen met het voorstellen van de spelwereld. De klasse \emph{Maze} zelf houdt de voorstelling van het doolhof bij.
Meer informatie over hoe de voorstelling concreet is verwezenlijkt is te vinden in sectie \ref{sec: Spelwereld}.
Andere klassen in dit pakket zijn \emph{Coordinate} en \emph{Location}. Beide zijn voorstellingen van de locatie van een \emph{Robot}.
Een \emph{Coordinate} geeft de co\"ordinaat aan van de sector waar de robot zich momenteel op bevindt. Een \emph{Location} geeft op centimeterniveau een locatie aan.
\emph{Barcode} stelt een barcode in het doolhof voor.

\begin{figure}[ht]
\centering
\includegraphics[width=0.6\linewidth]{mazeDiagram.png}
\caption{Vereenvoudigde voorstelling van de klassen in het mazepakket}
\label{fig: mazeDiagram}
\end{figure}

\subsubsection{gui}
% Misschien toch de verschillende klassen wat meer bespreken => Thomas
In dit pakket zitten alle klassen die verantwoordelijk zijn voor het organiseren en tonen van de grafische interface.
Deze wordt volledig uitgelegd in sectie \ref{sec: appendixGUI}.
De twee belangrijkste klassen in dit pakket zijn MainGui en GhostPanel.
GhostPanel laat een weergave zien van het doolhof zoals de ghost het zelf ziet.
MainGui toont het doolhof en de echte positie van pacman met gegevens uit de simulator.
Alle ownghosts die in de simulator zitten worden hier ook weergegeven, net als andere ghosts eens er gematcht is via een barcode.

\subsubsection{pacman.protocol}
\label{sec: protocol}
Zoals vermeld in \ref{sec: oudeProtocol} zijn er een paar aanpassingen gebeurd aan de klassen verantwoordelijk voor het protocol. Een sequence diagram van de verwerking is te vinden in figuur \ref{fig: protocolVerwerking}.

\begin{figure}[ht]
\centering
\includegraphics[width=0.9\linewidth]{ProtocolVerwerking.png}
\caption{Verloop van het verwerken van een inkomende boodschap.}
\label{fig: protocolVerwerking}
\end{figure}

Afhankelijk van wie de Information Expert
\footnote{Het principe van een Information Expert wordt gebruikt om te bepalen naar waar verantwoordelijkheden gedelegeerd moeten worden. De klasse met het meeste informatie voor de gewenste actie wordt de Information Expert genoemd.}
is voor het verwerken van de ingekomen boodschap roept de \emph{GameProtocolHandler} een eigen methode aan of een methode van de gepaste \emph{GhostProtocolHandler}.
Omdat sommige berichten enkel door een eigen ghost moeten verwerkt worden is er een onderscheid gemaakt tussen de ProtocolHandler van een gewone ghost en een eigen ghost. \\

Om de cohesie van de \emph{OwnGhost}klasse verder te verhogen werd het verzenden van boodschappen ook in een aparte klasse geplaatst, de \emph{GhostProtocolSender}.

\begin{figure}[ht]
\centering
\includegraphics[width=0.6\linewidth]{ProtocolHandlers.png}
\caption{Klassendiagram van de verschillende ProtocolHandlers}
\label{fig: protocolHandlers}
\end{figure}
   

\subsubsection{bluetoothCommunication}
In deze package zijn de klassen terug te vinden die zorgen voor de communicatie tussen de computer en de robot.  
De Bluetooth connectie tussen computer en robot gebeurt via een abstractielaag die gevormd wordt door de \emph{BTWrapper} en \emph{BTWrapperRobot}.
Deze bevatten methodes om data en commando's te zenden en te ontvangen.
Deze methodes zijn synchronized om ervoor te zorgen dat er telkens slechts vanuit \'e\'en plaats in het programma tegelijkertijd gezonden en ontvangen kan worden.
Hierbij wordt een protocol gevolgd dat stelt dat er steeds twee bytes moeten verzonden worden. De eerste byte geeft weer wat voor type data er volgt,
de tweede bevat de eigenlijke data die nodig is om de commando's uit te voeren. Als bijvoorbeeld de robot 40 cm vooruit moet rijden is de eerste byte 1 (= Travel) en de tweede byte  40.
De soorten commando's die doorgestuurd kunnen worden zijn gedefinieerd in de klasse \emph{Command}. De mogelijke types van data worden gedefinieerd in de klasse \emph{DataType}.
Een schematische voorstelling is te vinden in figuur \ref{fig:bluetooth}.

\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{bluetooth.jpg}
\caption{Schematische voorstelling van de Bluetoothconnectie}
\label{fig:bluetooth}
\end{figure}

\section{Strategie}
\label{sec: strategie}

\subsection{Demo 1}
\subsubsection{Explorer}
Gegeven de huidige locatie van de ghost zoekt deze strategie een pad naar de dichtstbijzijnde sector met een onverkende muur.
Indien er geen pad teruggegeven wordt is het doolhof volledig verkend.
Deze methode die dit pad berekent werkt door vanuit de locatie van de robot het doolhof te laten \textit{onderlopen} (met respect voor de muren).
De methode volgt virtueel elk pad dat de robot kan afleggen aan een constante snelheid (1 sector per iteratie van de hoofdlus).
Wanneer we een sector met een onverkende muur tegenkomen weten we dat dit de dichtstbijzijnde onverkende sector is.
De methode maakt gebruik van een recursieve datastructuur, dus we kunnen vanuit de gevonden sector het pad achterwaarts opbouwen.
De hoofdlus van de methode maakt gebruik van een gebied dat al gecontroleerd is en een actieve rand.
Het gecontroleerde gebied begint leeg, de actieve rand begint met enkel de startpositie van de robot.
In elke iteratie van de lus wordt de huidige actieve rand aan het gecontroleerde gebied toegevoegd en wordt de nieuwe actieve rand voor de volgende iteratie opgebouwd als alle sectoren die in 1 stap bereikt kunnen worden vanuit de huidige actieve rand.
Zodra een onverkende sector wordt toegevoegd aan de actieve rand stopt de lus en wordt het pad opgebouwd.\\
Zie figuur \ref{fig:getPathToClosestUnknown}.

\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{getPathToClosestUnknown.png}
\caption{Uitvoering van de hoofdlus van getPathToClosestUnknown() waarbij geen onverkende muren gevonden worden (laatste vier stappen weggelaten voor de bondigheid). Rood: de actieve rand - Blauw: gecontroleerd gebied.}
\label{fig:getPathToClosestUnknown}
\end{figure}
\subsection{Demo 2}
\subsubsection{MazeCorrector}
Deze strategie wordt geactiveerd als de robot de hele maze denkt verkend te hebben, maar Pac-man niet is tegengekomen of niet kan bereiken. Deze situatie kan bijvoorbeeld voorkomen als de robot foute waarden voor grenzen van een sector heeft gelezen en zichzelf bijgevolg heeft ingesloten.\\
In deze strategie zal de robot de muur rechts van hem volgen en elk paneel opnieuw verkennen.
\subsubsection{Samenwerking met andere robots}
\label{sec: SamenwerkingRobots}
Voor de samenwerking van de vier robots heeft elke robot drie extra mazes.
Deze mazes bevatten de informatie die de andere robots doorsturen via \emph{RabbitMQ}.
Wanneer twee robots over dezelfde barcode zijn gereden wordt er de methode \emph{match} in \emph{Maze} opgeroepen: deze methode legt de mazes over elkaar door een offset en eventueel een rotatie uit te rekenen.
Vervolgens kan de robot deze gegevens ook gebruiken want ze zijn vanaf dan beschikbaar in zijn eigen co\"ordinatensysteem.
Wanneer de robot nu \emph{getPathToClosestUnknown} oproept moet hij een array met gematchte mazes meegeven.
Als er nu informatie opgevraagd wordt over het doolhof kijkt de robot eerst in zijn eigen maze.
Als er geen eigen gegevens zijn over de sector wordt er gekeken in de gematchte mazes.
Indien er een consensus is tussen de verschillende mazes zal die informatie gebruikt worden
(om tot een consensus te komen wordt er geen rekening gehouden met onverkende sectoren). \\
\subsection{Demo 3}
\subsection{PacmanFinder}

In deze strategie probeert de robot naar Pac-man te rijden en hem in te sluiten.
Om dit te doen wordt er gebruik gemaakt van collaborrative diffusion. Hiervoor maken we gebruik van een algoritme dat zeer sterk lijkt op dat van getPathToClosestUnknown (zie hoger):
Het begin voor de actieve rand is de positie van Pac-man. Muren en andere robots blokkeren de spreiding van de actieve rand.
In een nieuw maze-object wordt, voor elke sector waar de actieve rand aan grenst, de aantrekkingswaarde opgeslagen. Deze waarde wordt, elke iteratie van de hoofdlus, verlaagd.

Wanneer het algoritme eindigt kiezen we de richting van de sector met hoogste aantrekkingswaarde die aan de robot grenst om naar toe te rijden, zonder dat er een muur in de weg zit.
Indien er zo geen richting gevonden kan worden staan we ofwel vlak naast Pac-man, of kunnen we Pac-man niet bereiken. In het eerste geval wachten we tot Pac-man beweegt, in het tweede schakelen we terug over op de MazeCorrector-strategie.

\subsection{Strategie-overgangen}
De overgangen tussen de drie strategie\"en verloopt volgens het volgende schema:
\begin{figure}[ht]
 \centering
 \includegraphics[width=\linewidth]{holy_trinity_of_strategy.png}
 \caption{Schema strategie-overgangen}
 \label{fig:holytrinityofstrategy}
\end{figure}
De overgangen gebeuren algemeen gesproken wanneer de huidige strategie geen richting meer kan berekenen om naartoe te rijden. Bijvoorbeeld, als Explorer null teruggeeft is er geen onverkende sector bereikbaar.
De grote uitzondering hierop is MazeCorrector, deze strategie kan nooit null teruggeven en laat na elke stap Explorer weer aan de beurt. Explorer zal de beurt dan meteen weer aan MazeCorrector teruggeven tenzij er een fout verbeterd was waardoor Explorer een andere beslissing neemt. Een andere mogelijkheid is dat Pac-man gevonden was. Explorer zal in dat geval de beurt aan PacmanFinder geven dan.

Indien PacmanFinder null teruggeeft betekent dat dat Pac-man niet bereikbaar is of dat we onze bestemming bereikt hebben. In het laatste geval hebben we gewonnen als we zien dat Pac-man ingesloten is, anders wachten we tot de situatie verandert (bijvoorbeeld als Pac-man ontsnapt).
Indien Pac-man niet bereikbaar is hebben we ergens een fout in ons doolhof, en zullen we overschakelen op de MazeCorrector-strategie.

Ten slotte, als we gewonnen hebben blijven we toch Pac-man in de gaten houden. Indien hij op een of andere manier nog ontsnapt gaan we terug naar start.

\section{Gedrag robot}
\label{sec: gedrag}
\subsection{Correctiemethodes}
\subsubsection{Demo 1}  
\label{sec: Correctiemethodes}
Aangezien de robot niet perfect rijdt doorheen de doolhof zijn er enkele correctiemethodes ge\"implementeerd.
Deze zijn nodig om de robot parallel aan de muur en in het midden van het paneel te zetten.
Op deze manier heeft de robot een optimale positie om de sector te verkennen en veilig naar de volgende sector te rijden.

\paragraph{Aanpassen van ori\"entatie}
\label{sec: AanpassenVanOrientatie}
Bij het rijden van de ene sector naar de volgende wordt (indien mogelijk) de afstand tot de linkse muur in de ene sector vergeleken met die in de volgende sector.
Als de robot recht heeft gereden, zouden deze twee waarden ongeveer gelijk moeten zijn.
Indien dit niet het geval is kan er vastgesteld worden welke hoek de robot maakt met de muren.
Uit onderstaande tekening kan worden afgeleid dat de hoek die de robot moet draaien om terug recht te staan (alpha), gelijk is aan de boogtangens van het verschil in afstand (einde-begin) gedeeld door 40 (de afstand die hij rechtdoor is gereden).
Deze correctie gebeurt enkel als de robot een muur aan zijn linkerkant heeft en naar de volgende sector vertrekt.
\begin{figure}[ht]
 \centering
 \includegraphics[width=\linewidth]{rechtzetten.png}
 \caption{De robot recht zetten in een sector}
 \label{fig:rechtzetten}
\end{figure}

\paragraph{Aanpassen van positie}
\label{sec: AanpassenVanPositie}
Wanneer de robot een sector scant en merkt dat hij te ver van het midden van de sector staat verplaatst hij zich om terug in het midden van de sector terecht te komen.
Een afstand tot een muur groter dan 25cm of kleiner dan 15cm wordt beschouwd als fout.

\subsubsection{Demo 2}
Om de robot optimaal het doolhof te laten verkennen is ervoor gekozen om onderstaande extra correctie toe te voegen.
De robot is zo ingesteld dat hij bij het verkennen van een sector een muur voor hem moeilijker detecteert.
Hierdoor zal hij vaak tegen een muur rijden.
\paragraph{Botsen tegen muur}    
Door de toevoeging van druksensoren vooraan de robot kan de robot detecteren wanneer hij frontaal tegen een muur rijdt.
Wanneer dit gebeurt, zet de robot in die richting een muur in zijn maze en rijdt hij achteruit.\\
Door de rechte voorkant van de robot zal hij zich bij een botsing met de muur ook loodrecht op deze muur zetten.
Ook weet hij hoe ver hij van het midden staat als hij tegen de muur botst en kan hij dus precies tot in het midden van de sector de optimale afstand achteruit rijden.\\
Deze correctie wordt enkel op de re\"ele robot toegepast.
\subsubsection{Demo 3}  
Omdat er natuurlijk niet gebotst mag worden met andere robots, kan de laatst vernoemde correctiemethode niet meer gebruikt worden.
Om geen nauwkeurigheid te verliezen bij het rijden, wordt een nieuwe correctiemethode toegevoegd.
Deze gebruikt de witte lijnen die de sectoren scheiden om zich op recht te zetten.\\
Er is ook beslist om de andere correctiemethodes minder te gebruiken op de re\"ele robot, om hem sneller te laten bewegen. Het aanpassen van de ori\"entatie op basis van de muren wordt niet meer gebruikt en het aanpassen van de positie gebeurt enkel op basis van de muur rechts van de robot.\\
\paragraph{Lijncorrectie}
Deze methode wordt geactiveerd wanneer de robot naar een volgende sector aan het rijden is.\\
Wanneer de robot over een witte lijn rijdt zal hij stoppen, daarna zal hij roteren tot hij de lijn terug registreert. Vervolgens roteert hij in de andere richting tot hij opnieuw de lijn registreert. Er wordt opgemeten hoe groot deze laatste rotatie was en de robot zal dan de helft van deze rotatie terugdraaien.\\
Dit zorgt ervoor dat de robot loodrecht op deze lijn staat. Ook weet hij nu dat hij nog maar een halve sector moet rijden om het midden van de volgende sector te bereiken.\\
Deze correctie wordt enkel op de re\"ele robot toegepast.

\subsection{Barcodes}
\subsubsection{Demo 2}
De robot registreert continu of er over zwart wordt gereden. Indien dit het geval is, wordt dit doorgestuurd naar de computer. \\
Nadat de robot op een sector is aangekomen, wordt nagegaan of er onderweg een zwarte waarde is geregistreerd.
In dit geval zal de robot (na het verkennen van de sector) achteruit rijden en van daar naar de volgende sector rijden.
Dit om er zeker van te zijn dat de robot over heel de barcode heeft gereden en niet stopt in het midden.

\subsection{Collision}
\subsubsection{Demo 3}
Bij het rijden naar een volgende sector meet de robot continu de afstand voor zich.
Als deze te klein wordt, detecteert hij daar een obstakel en rijdt hij terug.
Standaard interpreteert hij dit obstakel als een muur, maar als hij de absolute positie weet van andere robots kan hij het onderscheid maken tussen een muur en een robot.\\

\section{Spelwereld}
\label{sec: Spelwereld}
De spelwereld bestaat uit verschillende sectoren die gescheiden worden door een muur of een witte lijn.
We voeren een cartesiaans assenstelsel in om de posities in het doolhof te beschrijven.
De oorsprong van dit assenstelsel is de linkerbenedenhoek.
Een positieve x-waarde duidt op het aantal centimeter rechts van de oorsprong, een positieve y-waarde op het aantal centimeter boven de oorsprong.
De spelwereld kan op verschillende manieren worden voorgesteld.
Er zijn drie mogelijkheden uitgetest en uiteindelijk werd gekozen voor een dynamisch herschalende matrix met wrap-around indexering.
Dit houdt in dat het doolhof zich automatisch vergroot wanneer er een sector buiten het huidige bereik wordt toegevoegd.
De wrap-around betekent dat informatie in een torusstructuur wordt opgeslagen (als je verder dan de noordelijke kant van de kaart wandelt dan kom je aan de zuidkant terecht, idem ditto voor de west -en oostzijde.
Een vergelijking met de andere mogelijkheden voor een mazevoorstelling is te vinden in sectie \ref{sec: alternatieveMaze}
\\

\subsection{Voorstelling}
\subsubsection{Demo 1}
In de uiteindelijke voorstelling worden de gegevens opgeslagen met een structuur die zeer dicht bij een ASCII-art voorstelling van het doolhof aansluit.
In de even kolommen worden de verticale muren bijgehouden, in de oneven kolommen de horizontale.
In de voorstelling gebruiken we 0 voor onverkende muren, 1 voor een muur en 2 voor een doorgang.
We wijken hierbij af van de waardes zoals gespecifi\"eerd in het communicatieprotocol zodat we onze matrix niet manueel moeten initialiseren op de waarde voor onverkende muren.
Om de voorstelling makkelijk te visualiseren bekijk je een rij van de matrix per twee elementen.
Het eerste element toont aan of er een muur staat aan de westkant van de sector. Het tweede element stelt de aanwezigheid van een muur aan de zuidkant voor.
\\
De grote voordelen van deze voorstelling zijn het gemakkelijk cre\"eren en visueel voorstellen van een maze op basis van de ASCII-art en het effici\"ent opslaan van de gegevens van het doolhof.Er is geen probleem met het opslaan van negatieve sectoren of sectoren met hoge co\"ordinaat-nummers aangezien de \emph{Maze}klasse indexering abstraheert en de matrix herschaalt wanneer nodig.

Voorbeeld: \\
\begin{Verbatim}[samepage=true]
_ _ _ _ _ _ _ _ _      
|   |_   _|  _|  _|
|X| |  _|  _  |_  |
|_|_ _ _ _ _|_ _ _|
\end{Verbatim}

wordt opgeslagen als volgt:

\begin{Verbatim}[samepage=true]
{{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2},
{1,2,2,2,1,1,2,2,2,1,1,2,2,1,1,2,2,1,1},
{1,2,1,2,1,2,2,1,1,2,2,1,2,2,1,1,2,2,1},
{1,1,1,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,1}}
\end{Verbatim}

De \emph{Maze}klasse komt met een read- en write-methode waar men de sectorco\"ordinaten en de richting waarin men de muur wilt lezen/schrijven meegeeft,
en een boolean flag die aangeeft of deze co\"ordinaten in het eigen assenstelsel gegeven zijn of in het gekalibreerde (zie verder).
Deze methoden abstraheren de indexatie van de matrix, waardoor negatieve sector-co\"ordinaten mogelijk worden door middel van wrap-around indexing.
Om ervoor te zorgen dat een groot positief co\"ordinaat niet in het negatieve deel terechtkomt (of omgekeerd) zal de matrix herschaald worden (zie \ref{fig:matrixherschaling}) zodra de methode een co\"ordinaat tegenkomt dat deze grens overschrijdt.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.55]{matrixHerschalen.png}
\caption{Illustratie matrixherschaling, voorstelling van de Maze-matrix in het geheugen.}
\label{fig:matrixherschaling}
\end{figure}

Voorbeeld van een matrix waarbij de oorsprong niet in de linkerbenedenhoek van het doolhof ligt (en dus negatieve co\"ordinaten mogelijk zijn):
\begin{Verbatim}[samepage=true]
_ _ _||_|_ _ _ _ _|
_ _ _  _ _ _ _ _ _  
_|  _||   |_   _|   
|_  ||X| |  _|  _   
\end{Verbatim}

wordt opgeslagen als volgt:

\begin{Verbatim}[samepage=true]
{{1,2,1,2,1,1,1,1,1,1,2,1,2,1,2,1,2,1,1},
{1,1,2,2,1,1,1,2,2,2,1,1,2,2,2,1,1,2,2},
{2,1,1,2,2,1,1,2,1,2,1,2,2,1,1,2,2,1,2},
{1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2}}
\end{Verbatim}

De \emph{Maze}klasse biedt ook de mogelijkheid om de co\"ordinaten te kalibreren zodat deze overeenstemmen met die van een andere Maze.
Hiertoe dient men de co\"ordinaten en richting van een overeenkomstige sector in het huidige assenstelsel en de richting van de sector in het assenstelsel van de andere Maze in te geven.
De richting duidt op de relatieve ori\"entatie van de Maze.
\\

\section{Simulator}
\label{sec: Simulator}
Wanneer de robot niet in de echte wereld rijdt, moet het gedrag van elke sensor kunnen gesimuleerd worden alsof de robot in het echt aan het rondkijken is.
Dit is mogelijk omdat de simulator zowel de Maze, ColorMap als de echte posities van de robots bijhoudt.
In volgende subsecties wordt simulatie van de verschillende sensoren besproken.


\subsection{getMaxDistance}
\label{sec: getMaxDistance}
Deze methode geeft de maximale afstand die kan afgelegd worden in een gegeven richting vanuit een gegeven positie.
Conceptueel werkt deze methode door te raycasten\footnote{Het principe achter ray casting is dat je vanuit een punt een straal uitstuurt en dan de afstand berekent tot het eerste object dat de straal onderbreekt.
In het doolhof stelt het punt de ultrasone sensor voor en zijn de muren de objecten die de straal kunnen onderbreken.} op de randen van de huidige sector en te checken of deze rand een muur is.
Indien dit niet het geval is, wordt de methode iteratief herhaald met als nieuwe positie het resultaat van de raycast en worden de resultaten van de verschillende iteraties opgeteld.
\\
Meer in detail werkt het algoritme als volgt:
eerst wordt de cos en sin van de hoek (CCW) tussen de gegeven richting en de positieve x-as berekend.
Uit deze waarden kunnen twee rechten afgeleidt worden waarmee de ray snijdt (deze rechten vallen samen met de randen van de huidige sector).
Met andere woorden: er worden twee snijpunten berekend waarvan telkens \'e\'en co\"ordinaatgetal (x of y) gekend is.
Het tweede co\"ordinaatgetal van deze punten wordt berekend door te stellen dat deze punten gelegen zijn op de ray.
Het punt dat snijdt met een zijde van de huidige sector is het punt dat het dichtst bij de gegeven positie ligt.
Vervolgens wordt er gecheckt of de zijde waar het gekozen punt op ligt een muur is, en volgt er eventueel een iteratie.
Zie figuur \ref{fig:getMaxDistance}.

\begin{figure}[!h]
\centering
\includegraphics[scale=0.7]{getMaxDistance.png}
\caption{Het principe van getMaxDistance weergegeven.}
\label{fig:getMaxDistance}
\end{figure}

\subsection{Ultrasone sensor}
\label{sec: UltrasoneSensor}
Het simuleren van de ultrasone sensor gebeurt op basis van raycasting.
Concreet wordt een \emph{getDistance} oproep gesimuleerd door \emph{getMaxDistance} (zie sectie \ref{sec: getMaxDistance}).
\subsubsection{Onnauwkeurigheden}
\label{sec: onnauwkeurigheidUltrasone}

Om onnauwkeurigheden te simuleren wordt er gebruik gemaakt van de werkelijke afwijking van de sensor.
De standaardafwijking en het gemiddelde voor deze sensor werden bepaald bij de testen van de ultrasone sensor(zie sectie \ref{sec: testUltrasone}.
Met behulp van deze waarden kan er dan een Gauss-curve opgesteld worden.  Deze curve kan dan in verband gebracht worden met de standaard normale verdeling door middel van een schalering met de standaarddeviatie en een verschuiving met de gemiddelde waarde.
De klasse random heeft een method om een random waarde te genereren van de standaardnormale verdeling.  Op deze manier is er een realistische random waarde gecre\"eerd die gesuperponeerd kan worden op de exact gemeten waarde.


\subsection{Infraroodsensor}
De methode begint met de hoeksector (zie figuur \ref{fig:infrarood}) te bepalen die teruggegeven zou worden indien er geen muur tussen Pac-man en de infrarood sensor zou staan.
Men begint met een vector op te stellen naar Pac-man vanuit de locatie van de sensor, en deze te roteren zodat hij relatief is aan de positie en de ori\"entatie van de sensor.
De lengte van deze vector houden we apart bij, deze zullen we later gebruiken. Daarna normaliseren we de vector.
Op basis van de x -en y-componenten van deze vector (die overeenstemmen met de cosinus en sinus van de hoek die deze vector met de x-as maakt) kunnen we dan de hoeksector bepalen zoals op de afbeelding.
zwart is gebruikt voor het assenstelsel en de eenheidscirkel waarop de genormaliseerde vector ligt, blauw voor de afbakening tussen de hoeksectoren en met rood worden de gebieden aangeduid waarmee de hoeksector bepaald wordt

\label{sec: Infraroodsensor}
\begin{figure}[ht]
\centering
\includegraphics[scale=0.4]{infrarood.png}
\caption{De voorstelling van de infraroodsensor.}
\label{fig:infrarood}
\end{figure}

Tenslotte bepalen we de zichaarheid van Pac-man door de eerder opgeslagen afstand te vergelijken met de maximale afstand tot de eerste blokkerende muur in de richting van de sensor.
Deze laatste wordt bepaald op een analoge manier als bij de ultrasone sensor op basis van het getMaxDistance methode (sectie \ref{sec: getMaxDistance}).

\subsubsection{Onnauwkeurigheden}
Deze worden op een analoge manier berekend als bij de ultrasone sensor (zie sectie \ref{sec: onnauwkeurigheidUltrasone}) alleen worden er hier andere waarden voor de standaarddeviatie en het gemiddelde gebruikt.  
De gebruikte waarden hiervoor zijn te vinden in sectie \ref{sec: testIR}.

\subsection{Lichtsensor}
Om de lichtsensor te simuleren wordt er een \emph{ColorMap} opgesteld.
Dit gebeurt automatisch op basis van een \emph{Maze} object (barcodes kunnen achteraf toegevoegd worden).
Deze map bestaat uit sectoren die elk \'e\'en paneel ($40cm^2$) van het speelveld voorstellen.
Elke sector bevat een afbeelding met de kleurinformatie van die sector.
Deze afbeeldingen hebben een resolutie van 40 op 40 pixels, zodat elke pixel een oppervlakte van $1 cm^2$ voorstelt.
De klasse ColorMap bevat een belangrijke methode, \emph{getSensorReading}, die op basis van de meegegeven positie simuleert wat de lichtsensor zou registreren.
Om deze gesimuleerde waarde te berekenen, wordt er eerst berekend of de sensor (met in te stellen zicht-radius) pixels ziet op een sector.
Indien dit zo is, wordt er op die sector bepaald welke pixels volledig binnen de sensorradius vallen en welke er slechts gedeeltelijk binnen liggen.
Vervolgens wordt er een gewogen gemiddelde grijswaarde berekend van de pixels die de sensor kan waarnemen,
waarbij pixels waarvan het midden binnen [sensorradius-0.5cm] liggen een gewicht van 100\% krijgen en pixels met een midden tussen [sensorradius-0.5cm; sensorradius+0.5cm] een gewicht van 50\% krijgen.
Deze benadering zou  nog verfijnd kunnen worden door nauwkeuriger te berekenen hoe groot het deel van de pixel is dat binnen de sensorradius valt.
\label{sec: Lichtsensor}
\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{lichtsensor.jpg}
\caption{De werking van de lichtsensor.}
\label{fig:lichtsensor}
\end{figure}
\subsubsection{Onnauwkeurigheden}
Om onnauwkeurigheden te simuleren, wordt er in \emph{ColorMap} een tweede lijst van \emph{BufferedImages} bijgehouden die voor elke sector een distortie-afbeelding bevat.
Deze afbeelding wordt bij het initialiseren per sector random gekozen uit een aantal verschillende distortie-afbeeldingen.
Deze afbeeldingen werden in Gimp gegenereerd door difference clouds te renderen met als basis een witte achtergrond,
en vervolgens de bekomen afbeelding zo te manipuleren dat de gemiddelde grijswaarde overeenkomt met de grijswaare van bruin/houtkleur.
Een in te stellen distortie-parameter controleert in welke mate de grijswaarden van de distortie-afbeeldingen doorwegen bij het berekenen van de grijswaarde van een pixel.
Concreet wordt de grijswaarde van een pixel berekent met volgende formule:\\     
$grayValue = ((100-distortie)*undistortedValue + distortie * distortedValue) *0.01$

\subsection{Pilot}
\label{sec: pilot}
Het rijden van de robot wordt gesimuleerd in de klasse \emph{Pilot}. Aan de hand van de snelheid van de robot kan bepaald worden hoe lang hij over een bepaalde afstand zal doen.
Gedurende deze tijd wordt de positie van de robot om de tien miliseconden aangepast. Dit gebeurt gelijkaardig bij het roteren.
Ook wordt er nagegaan dat de robot niet door een virtuele muur rijdt. Dit gebeurt met de raycaster.  
\subsubsection{Onnauwkeurigheden}
Ook de onnauwkeurigheid van de motoren wordt gesimuleerd.  Er wordt rekening gehouden met een onnauwkeurigheid op de afgelegde afstand als ook op de rotatiebeweging van de robot.
De waarden die hiervoor gebruikt worden die zijn berekend bij het testen van de motoren in het eerste semester(zie sectie \ref{sec: testMotoren}).

\section{Resultaten}
\label{sec: Resultaten}
Deze sectie beschrijft het verloop van de verschillende demo's. We bespreken wat er werkte en wat nog op punt gesteld moet worden.
Door de opeenvolging van de resultaten van de verschillende demo's bekomen we een goed overzicht van de evolutie van het project.
\subsection{Demo 1}
\label{sec: ResultatenDemo1}
De resultaten van deze demo waren niet zo goed aangezien de robot niet ver reed en ook de GUI voor problemen zorgde.
Dit kwam op zich niet als een verassing aangezien we nog volop bezig waren met dit af te werken en we daardoor geen tijd hadden om dit goed te testen en de fouten eruit te halen.  
\begin{itemize}
\item De problemen met de simulator waren dat de GUI steeds aan het wachten was tot de robot een beslissing had genomen voordat de GUI opnieuw zijn waarden update.
    Dit zorgde ervoor dat je enkel in schokken de gesimuleerde waarden te zien kreeg.
\item De problemen met de robot waren van verschillende aard: hij reed niet nauwkeurig en we hadden nog geen tijd gehad om de correcties te implementeren.
    Verder las de ultrasone sensor gemakkelijk foute waarden waardoor zijn map en alle verdere handelingen volledig de mist in gingen. Hier werd in de implementatie nog geen rekening mee gehouden.
\item Tot slot kon de robot ook Pac-man niet ontwijken aangezien dit nog niet ge\"implementeerd was.
\end{itemize}

\subsection{Demo 2}
\label{sec: ResultatenDemo2}
Het resultaat van deze demo was aanzienlijk beter dan de vorige. De correctiemethodes van de robot waren verbeterd, zodat de fysieke robot quasi probleemloos het doolhof kon verkennen.\\
Wel waren er nog een aantal problemen; zo botste de robot nog geregeld op anderen en ook bij het lezen van barcodes gebeurde er een onverwachte fout.
\subsection{Demo 3}
\label{sec: ResultatenDemo3}
Door de nieuwe aanpak van correcties kon de robot probleemloos het parcours verkennen, aan een hogere snelheid dan voordien.\\
Ook botsingen met andere robots werden grotendeels voorkomen en barcodes werden correct gelezen.\\
Bij de hybride simulatie (met 3 virtuele robots en 1 echte) werd pacman gevangen. Hier bewogen de virtuele robots wel aanzienlijk sneller dan de echte robot. \\
Op het gedeelte waar 4 re\"ele robots moesten samenrijden presteerde de robot ook goed. Doordat het doolhof redelijk groot was en er veel robots crashten werd het doolhof nooit volledig verkend, waardoor de robot niet achter pacman aanging. Ook had de robot enkele problemen met de vele foute informatie die werd doorgestuurd door enkele robots die telkens opnieuw tegen een muur reden nadat ze met ons gematched waren. Hierdoor moest de robot al deze sectoren zelf weer exploren waardoor het spel traag vooruit ging. Bij het reconnecten van een van de andere robots liep er iets vast in onze eigen code. Toen we hierna zelf probeerde te reconnecten konden we echter niet starten aangezien \"e\"en van de andere teams geen RENAME doorstuurde.
Onze robot reed redelijk langzaam vergeleken met de anderen, maar dit werd zeker gecompenseerd door het feit dat we niet fysiek crashten en zo op eigen kracht de volledige map kon verkennen.



\section{Conclusie}
\label{sec: Conclusie}
Hierin worden de bedenking omtrent de resultaten van de demo's geformuleerd. Het geeft weer welke aanpassingen er gedaan moeten worden om eventuele problemen in de demo op te lossen.

\subsection{Demo 1}
\label{sec: ConclusieDemo1}
Deze demo kwam voor ons te vroeg, aangezien we niet genoeg tijd hadden om ons goed voor te bereiden.
\begin{itemize}
\item Het gedrag van de robot was nog niet naar behoren ge\"implementeerd.
\item Het grootste deel van de tijd zijn we bezig geweest aan de simulator omdat dit de grootste brok werk leek. Pas op het einde bleek dan dat we in tijdsnood zaten.
\item Om dezelfde reden is er niet goed nagedacht over onze presentatie en hoe we ons project zo goed mogelijk moesten voorstellen, dit zorgde ervoor dat de demo chaotisch verliep.
Met zicht op volgende demo zullen er betere afspraken gemaakt worden over wie wat doet zodat het beter oogt voor de jury.
\item Er valt nog veel werk te doen voor volgende demo aangezien de robot eerst nog aan de eisen van de vorige demo moet voldoen voordat er kan gewerkt worden aan demo 2.
De belangrijkste zaken hierbij zijn het grondig testen en implementeren van de robot als ook het werkende krijgen van de grafische interface.
\item Ook moet het lezen van barcodes en het mappen van de verschillende mazes op elkaar nog eens nagekeken worden.
\item Tot slot zijn er nog enkele belangrijke veranderingen die in het design dienen doorgevoerd te worden.
Wegens de korte deadline tot demo 2 zullen deze in de paasvakantie worden doorgevoerd.
Dit zijn vooral veranderingen die nodig zijn om het ontwerp logischer te maken zodat het gebruiksvriendelijker wordt.
\end{itemize}

\subsection{Demo 2}
\label{sec: ConclusieDemo2}
Doordat we meer hebben kunnen testen, waren we beter voorbereid en verliep de demo vlotter dan de vorige. Ook de presentatie zelf
verliep veel minder chaotisch. \\
Het oplossen van de botsingen met andere robots zal een prioriteit worden voor de laatste demo.
\subsection{Demo 3}
\label{sec: ConclusieDemo3}
Door het herbekijken van het correctiegedrag reed de robot beter en sneller dan voordien. Het doolhof werd echter niet volledig verkend op de gezamelijke demo. Om zeker te weten dat pacman ingesloten is, is dit echter noodzakelijk. \\






\section{Kritische analyse}
\label{sec: kritischeAnalyse}

\subsection{Sterke punten}
\label{sec: sterkePunten}
\begin{enumerate}
\item De robot rijdt robuust met relatief weinig correcties.
\item De simulator is realistisch en kan dus goed gebruikt worden om te testen.
\item Het doolhof wordt eerst volledig verkend, voordat pacman wordt achtervolgd. Hierdoor kan correct bepaald worden wanneer het spel gewonnen is.
\end{enumerate}
\subsection{Zwakke punten}
\label{sec: zwakkePunten}
\begin{enumerate}
\item De robot beweegt traag.
\item Het software ontwerp kan nog verbeterd worden (zie sectie hieronder).
\item Het gedrag van de robot, als hij de maze correct heeft verkend en pacman niet heeft gezien, kan nog verbeterd worden. Dan zal hij de mazecorrector activeren (die de rechtse muur zal volgen). Dit algoritme is eigenlijk gemaakt om te ontsnappen uit een deelmaze waarin de robot is ingesloten (als hij bijvoorbeeld ergens foutief een muur heeft gelezen).
\end{enumerate}



\subsection{Mogelijke verbeteringen}
Hoewel er grote refactorings zijn gebeurd blijven er een paar delen van het softwareontwerp die beter kunnen. Een voorbeeld hiervan is het \emph{Visitor}pattern gebruiken om informatie op te vragen voor de GUI.
In figuur \ref{fig: visitorKlasseDiagram} is de Client dan de GUI-klasse. De elementen zijn de \emph{OwnGhosts}. Een \emph{ConcreteVisitor} zal in zijn \emph{visit}-methode de sensorwaarden opvragen en terugsturen naar de GUI.

\begin{figure}[ht]
\centering
\includegraphics[width=0.5\linewidth]{visitorClassDiagram.pdf}
\caption{Klassendiagram van het Visitorpatroon}
\label{fig: visitorKlasseDiagram}
\end{figure}

Dit zou een kleine verbetering zijn op het huidige systeem van een \emph{DataCollector} die een ghost bijhoudt en \'e\'enmaal de sensorwaarden opvraagt. \\
Een volgende mogelijke verbetering is het invoeren van een \emph{Chain of Command} voor de strategie.
Door voor de verschillende situaties een eigen \emph{Handler} te geven worden de strategische beslissingen veel duidelijker. De hierarchie zou er bijvoorbeeld als volgt kunnen uitzien (prioriteiten gaan van hoog naar laag):
\begin{enumerate}
\item Pac-man gezien $\rightarrow$ rij ernaar toe
\item Onbekende sector $\rightarrow$ rij ernaar toe
\item Bekende sector (niet in plan van andere robots) $\rightarrow$ rij ernaar toe
\item Bekende sector (plan van andere robots) $\rightarrow$ rij ernaar toe
\item last resort $\rightarrow$ rechtdoor rijden
\end{enumerate}

Beide verbeteringen zouden het rijgedrag van de robot niet verbeteren maar zouden het debuggen en algemeen gebruik vergemakkelijken.

\begin{figure}[ht]
\centering
\includegraphics[scale=2]{chain.png}
\caption{Klassendiagram van het Chain of Responsibility patroon}
\label{fig: chainKlasseDiagram}
\end{figure}

\section{Beschrijving van het proces}
Tijdens dit project hebben we enkele moeilijkheden tegengekomen. E\'en van deze moeilijkheden was rekening houden met het feit dat de hardware niet altijd perfect is en soms onverwachte resultaten kan geven. Dit zorgde er uiteindelijk voor dat we soms te weinig tijd hadden voor bepaalde onderdelen omdat we verwacht hadden dat als de software correct is het zou werken. Een ander probleem dat we soms hadden was het vinden van een vrij moment dat we allemaal konden werken. Aangezien we uit verschillende richtingen komen waren er relatief weinig mogelijkheden om met het volledige team samen te werken. Dit hebben we uiteindelijk toch opgelost. We hebben zo veel mogelijk gebruik gemaakt van de momenten dat iedereen kon komen, anderzijds hebben we ook vaak in shifts gewerkt. Zo kwamen soms de informatici in de voormiddag werken omdat ze toen vrij hadden en de ingenieurs in de namiddag toen zij vrij hadden.\\
Tenslotte lag onze prioriteit in het begin niet helemaal juist. Er is toen veel tijd gestoken in de simulator zo realistisch mogelijk te maken, terwijl onze robot het doolhof nog niet goed kon verkennen.

    Gedurende dit jaar hebben we toch enkele belangrijke lessen geleerd. We weten nu dat we meer tijd moeten vrij maken voor het fysiek testen en niet te veel op de software alleen mogen vertrouwen. Ook in verband met planning en samenwerking hebben we veel bijgeleerd. Een groot project vereist duidelijke communicatie tussen de teamleden en een duidelijke werkverdeling waarin iedereen weet wat hij moet doen. Ten slotte hebben we nog bijgeleerd over het belang van het voorbereiden van presentaties. Na de rampzalige eerste demo toen we een heel chaotische presentatie hadden geleverd, hebben we besloten om deze zaken voortaan
beter voor te bereiden en enkele keren te oefenen.

Het werken in team verliep over het algemeen goed. We hadden altijd duidelijke afspraken over werkmomenten en wie er aanwezig ging zijn. Alle communicatie verliep oftewel tijdens de werkmomenten of via mail. Alle informatie over wie wanneer gewerkt had en aan wat werd constant bijgehouden in een google docs bestand, deze werd door iedereen persoonlijk ingevuld. In het team was er niemand met een echte leiderpositie, alle afspraken of planning werden door de groep samen gemaakt tijdens de eindvergadering na elk werkmoment. Dit had als voordeel dat iedereen zijn stem gehoord werd en iedereen samen de verantwoordelijkheid droeg voor het project.

Uit de laatste demo\'s bleek dat het moeilijkste is om de verschillende robots op elkaar af te stemmen, zeker als iedereen een licht andere interpretatie van het protocol heeft.  Hier blijkt opnieuw dat niet genoeg met iedereen getest kan worden, maar aangezien niet iedereen tijdig klaar was met de werking van de eigen robot was het niet mogelijk om dit helemaal in orde te krijgen. De enigste wat je kan doen is op zo veel mogelijk voorbereid te zijn, want er gebeuren altijd onverwachte zaken als je met anderen samen werkt.


\section{Werkverdeling}
In volgende tabellen staat de werkverdeling van elke persoon.  In de eerste tabel staat de vrijetijdsbesteding(in uren) per week van het semester(met Paasvakantie aangezien er ook dan gewerkt is). \\
\\
\begin{tabular}{| c | c | c |c | c | c |c | c | c |c | c | c |c |c |}
  \hline
  Naam & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 & 13\\
  \hline \hline
  Maarten & 5.5 & 14 & 10.5 & 27 & 20 & 25 & 3.5 & 0 & 22 & 4.5 & 9 & 34.5 & 9.5 \\
   \hline
  Simon & 4.5 & 16.75 & 10.75 & 27 & 20 & 19.5 & 6 & 0 & 17 & 4.5 & 9.75 & 34.5 & 4.5\\
   \hline
  Thomas & 3.5 & 17 & 10 & 8.5 & 6 & 16 & 0 & 0 & 17.5 & 4.5 & 5.5 & 20.75 & 5.5\\
  \hline
  Niels & 4.5 & 15 & 11 & 28 & 19.5 & 18.5 & 5 & 0 & 23.5 & 4.5 & 9.75 & 33 & 9.5\\
  \hline
  Harm & 5.5 & 3.5 & 5 & 16 & 8.5 & 14.5 & 0 & 0 & 29.75 & 2 & 14 & 16.5 & 9.5\\
  \hline
  Jeroen & 7 & 8 & 10.5 & 13 & 13 & 12 & 3 & 0 & 18 & 3.5 & 10 & 15.5 & 8\\
  \hline
 \end{tabular}\\

In volgende tabel staat dan het totaal aantal gewerkte uren van zowel de sessie als de vrije tijd.
Harm heeft minder sessie uren omdat hij elke maandag om 6 uur naar de les moest.  Welke regelingen hiervoor getroffen zijn, staat beschreven in volgende sectie \ref{sec: samenwerking}\\
\\
\begin{tabular}{| c | c | c | c|}
 \hline
 Persoon & Vrije tijd & Sessie & totaal\\
 \hline \hline
 Maarten & 185 & 55 & 240 \\
 \hline
 Thomas & 115 & 55 & 170 \\
 \hline
 Niels & 179.25 & 55 & 234.25 \\
 \hline
 Simon & 174.75 & 55 & 229.75 \\
 \hline
 Harm & 124.75 & 44 & 168.75 \\
 \hline
 Jeroen & 121.5 & 55 & 176.5 \\
 \hline
\end{tabular}\\

In volgende tabel staat beschreven waar elke persoon aan gewerkt heeft. Buiten al deze taken heeft iedereen ook alles moeten testen en zijn eigen deel in het verslag te zetten tezamen met het nalezen van het volledige verslag.
\subsection{Taakverdeling}
\label{sec: taakverdeling}
\begin{tabular}{| c | c | c | c|}
 \hline
 Persoon & taken & & \\
 \hline \hline
 Maarten &  Werking re\"ele robot & bluetooth & \\
 \hline
 Thomas &  GUI & testen/debuggen & \\
 \hline
 Niels &  simulator & implementatie infraroodsensor & matching robot \\
 \hline
 Simon &  simuleren lichtsensor & werking re\"ele robot & \\
 \hline
 Harm & structuur programma & rabbitMQ en protocol & gedistribueerd\\
 \hline
 Jeroen & algoritmes implementeren & datastructuur  maze & \\
 \hline
\end{tabular}
\\
\appendix
\section{Appendix}
\label{sec: Appendix}

\subsection{Beoordeling team Blauw}
\label{sec: beoordeling}

\subsubsection{Verslag}
\begin{enumerate}
 \item grote issues
 \begin{itemize}
    \item De lichtsensor wordt niet echt gesimuleerd, maar gebruikt voorkennis van het maze voor het opvragen van lichtwaarden. Om een echte simulator te cre\"eren is het toch de bedoeling dat je de input simuleert die een sensor krijgt om daarmee de waarden die de sensor zou geven te berekenen.
    \item Je rijdt nog niet naar \emph{Pac-man} wat wel verwacht werd in demo 2.
    \item User interface functionaliteit: hoe bepalen jullie de grootte van jullie maze?  Kan het niet gebeuren dat je robot buiten je voorstelling van de maze rijdt en hoe lossen jullie dit dan op?
 \end{itemize}
 \item kleine issues
 \begin{itemize}
    \item Bij het gebruik van \emph{subMazes} wordt gezegd dat ze rekening houden met onzekere waarden, maar hoe is nergens vermeld in jullie verslag?
    \item Bij de simulator over demo 2: Jullie maken gebruik van een randomizer bij het simuleren van de afstandsensor, maar er wordt niet echt uitgelegd wat die doet, op welke manier deze ge\"implementeerd is.
    \item Er mag een verwijzing of korte uitleg bij over het \emph{Dijkstra algoritme}, zodat je direct een goed beeld krijgt van wat het algoritme is.
    \item Heel grote passage over de bouw van de robot. Het lijkt ons beter als je van de uiteindelijke robot vertrekt en dan enkele grote aanpassingen weergeeft.
    \item Vaak staat er bij de sensoren dat er heel veel testen zijn uitgevoerd voor optimalisatie, maar er staat geen verwijzing naar resultaten/gegevens van deze testen.
    \item Bij design van de robot staat er dat er hierbij rekening is gehouden met een test over de hoogte van de infraroodbal. In het verslag staat geen verwijzing naar deze test.
    \item Wat meer uitleg over de messaging klasse is wel handig voor het begrijpen van het softwareontwerp. Wat houdt deze laag boven op \emph{RabbitMQ} in?
    \item Verwijzing naar het echte protocol in een bijlage/op Toledo is wel handig. Het wordt nu regelmatig vermeld zonder dat je echt weet wat het inhoud.
    \item In de inleiding geef je meestal weer hoe je het verslag opbouwt: nu lijkt het zeer sterk op je probleemstelling.
    \item Pg 18 ivm met ontwerpbeslissingen staat de binnengekregen informatie is onzeker. Dit geldt voor alle info die je gebruikt, ook voor de info van je eigen robot.
    \item Bij de aantrekkingskrachten staat niet weergegeven wat de verhoudingen zijn van de afstoting en aantrekkingskrachten. Hoe is de aantrekking naar pacman en de afstoting van andere robots bepaald geweest?
    \item Bij simulator van de virtuele robot (afstandsensor): Hebben jullie er rekening mee gehouden dat een robot als een muur wordt voorgesteld, is er een mogelijkheid om dit te corrigeren?
 \end{itemize}
 \item Schrijfstijl
 \begin{itemize}
    \item Nog eens de zinnen controleren op lidwoorden, die ontbreken vaak of er zijn er teveel door het sleutelen aan de zinnen.
    \item Bij de simulator wordt er heel vaak gebruik gemaakt van opsommingen, het oogt mooier als dit in paragrafen wordt weergegeven.
    \item figuur 7 neemt een heel blad in, is dit nodig? Zo groot is de figuur toch niet.
    \item Wat is de betekenis van cursief? Alle klassen, alle termen (\emph{Dijkstra} dan weer niet...): welke lijn zit hier in? Probeer consequent te zijn.
    \item Onderdeel over influences: die lange strepen bij de opsomming staan hier vreemd. In de delen hiervoor waren die niet aanwezig. Dit geeft een heel andere schrijfstijl weer.
 \end{itemize}
 \item Typos
 \begin{itemize}
    \item p3 laatste regel: zijn moet weg
    \item p6 tweede subdeel: verandert
    \item p13 robotNavigator: \ldots worden uitgevoerd op de robot
    \item p18 4de lijn staat er te veel
    \item p19: ge\"iterpreteerd
    \item p20 6de lijn: geen muur is ipv deze open is
    \item p21: laatste puntje: ge\"induceerd
    \item p28: matchten
    \item algemeen: LateX heeft de \"i regelmatig geschrapt
 \end{itemize}
\end{enumerate}

\subsubsection{Presentatie}
\begin{enumerate}
 \item Demonstratie
 \begin{itemize}
    \item De robot is heel gevoelig aan de calibratie van de lichtsensor: misschien is het stabieler om gebruik te maken van raw values
    \item robot deed nogal raar: hij reed precies heel de tijd hetzelfde stukje, een breedte eerst algoritme had misschien een betere performantie gegeven?
 \end{itemize}
 \item Antwoorden op vragen
 \begin{itemize}
    \item volgens het verslag gaat de influence niet door muren, vanuit de presentatie leek het alsof deze wel door muren kan gaan of hebben we dit fout begrepen?
 \end{itemize}
\end{enumerate}

\subsubsection{Positieve punten}
\begin{itemize}
 \item Mooie paragraaf over de verschillende correctiemethodes die je gebruikt.
 \item Zeer handig dat je nu reeds \emph{Pac-man} manueel kan besturen om zo bepaalde zaken snel te testen.
 \item De afscherming en abstractie maken van virtuele en fysieke robot wordt op zeer goede manier gedaan.
 \item Je kan op eenvoudige en snelle wijze een extra virtuele robot toevoegen aan het spel, zeer praktisch.
\end{itemize}

\subsection{Beoordeling door team Brons}
\subsubsection{Verslag}
\paragraph{Grote issues (Inhoud)}
\begin{itemize}
\item de samenhang van het verslag is niet altijd duidelijk bv. samenhang tussen verschillende onderdelen van het deel 'Softwaredesign'
\item sommige delen zijn ingewikkeld uitgelegd (KISS-principe) bv. getMaxDistance()-methode moeilijk uitgelegd in verslag
\item welk algoritme voor het kortste pad naar Pacman wordt gebruikt en waarom een tweede onaangesloten druksensor werd gebruikt, is door jullie
team overdacht (bleek uit presentatie) maar niet in het verslag opgenomen
\end{itemize}
\paragraph{Kleinere opmerkingen (Inhoud)}
\begin{itemize}
\item heeft het paragraafje 2.4.6 Pacman nut?
\item er is geen reden waarom de klasse Pacman een subklasse van de klasse Robot zou zijn
\item deeltje 2.4.11 verwijst naar meer detail in 2.4.11 (loop!)
\item raycasting wordt vaak vermeld in verslag vooraleer het begrip wordt uitgelegd
\item afb p.14 brengt niets bij, ringstructuur niet duidelijk
\end{itemize}

\paragraph{Stylistische opmerkingen}
\begin{itemize}
\item typos: kunnnen p.8, hetq p.13, gespecifi\"erd p.13, emphPacman p.19
\item taalgebruik: dt-fouten! ``werd verandert'' p.6, ``iets dat aanduid'' p.9, ``hadden gefocused'' p.19, ``de infraroodsensor definieerd'' p.23
\item spreektaal: ``af te implementeren'' p.18, ``in een logische structuur te steken'' p.19, ``drie onverkende richtingen die hij op kan'', ``las de ultrasone sensor rap een fout'' p.19
\end{itemize}
\subsubsection{Presentatie}
\paragraph{Presentatie zelf}
\begin{itemize}
\item bij de demo met 4 fysieke robots bleef jullie team barcodes doorsturen
\item bij de demo met 1 fysieke robot viel de robot stil
\item er is niet voor een barcode gestart hoewel we er wel om hadden gevraagd
\item de GIU leverde nog problemen op (trage weergave, ...)
\end{itemize}
\paragraph{Antwoorden op Vragen}
\begin{itemize}
\item zeer duidelijk, verhelderde de vragen bij het verslag
\end{itemize}
\subsubsection{Positieve punten}
\begin{itemize}
\item het testen van de infraroodsensor is een goed geschreven passage, er werd voldoende getest
\item de presentatie bevatte duidelijke uitleg en verliep vlot
\end{itemize}

\subsection{GUI}
\label{sec: appendixGUI}
Voor de grafische interface wordt er vanaf nu gebruik  gemaakt van Java Swing.
In plaats van enkel de basis drawfuncties zoals het tekenen van lijnen te gebruiken is er nu ook \emph{drawImage(...)} die gebruikt kan worden om afbeeldingen te tekenen.
Door afbeeldingen te tekenen wordt er minder tijd verspild aan het design en is het gemakkelijker om later nog aanpassingen te maken door de afbeelding te veranderen.
De lay-out is ingedeeld in verschillende panelen: links een groot vierkant paneel en rechts vier kleine panelen onder elkaar (\ref{fig:simulatorview}).
In het linkse paneel wordt het doolhof grafisch weergegeven.
In de voorstelling van het doolhof wordt \'{e}\'{e}n centimeter weergeven als \'{e}\'{e}n pixel.
Om een doolhof dat groter is dan het voorziene venster weer te geven wordt er gebruik gemaakt van een view en offsets.
Er zijn telkens 15x15 sectoren zichtbaar op  het groot paneel in de gui en door met de muis te slepen kan je door het maze manoeuvreren. In deze voorstelling worden Pac-man en de OwnGhosts die in de simulator zitten weergegeven. Aangezien deze voorstelling werkt met de continue simulator worden de bewegingen en rotaties van de OwnGhosts ook continu weergegeven. Eens er gematcht is via barcodes met andere spelers zullen deze verschijnen in de voorstelling van het doolhof. Door op enter te drukken kan er gewisseld worden tussen de normale weergave en weergave van de colorMap (\ref{fig:colorMapMaze}). De vier kleinere panelen aan de zijkant geven weer welke spelers er in de game zitten.
Bovenaan het paneel staat telkens de naam van de ghost. Dezelfde naam is ook te vinden bij de weergave van elke robot in het doolhof. Voor de OwnGhosts wordt ook weergegeven welke strategie ze op de moment gebruiken om hun bewegingen te bepalen.
Onder de naam staat voor elke speler een afbeelding van hoe die speler wordt afgebeeld in de GUI.
Als je op de kleine panelen klikt wordt er een GhostPanel (\ref{fig:GhostOwnMaze}) gemaakt, deze opent een nieuw venster waarin de maze getekend wordt dat die ghost al verkend heeft. Aangezien deze weergave enkel werkt met de data doorgestuurd via RabbitMQ worden de ghosts niet continu weergegeven maar per panel. Indien de ghost die je aan het bekijken bent gematcht heeft met andere spelers worden deze ook weergegeven door de afbeelding die in de main GUI staat. Eens een Ownghost PacmanFinder als strategie heeft wordt in deze voorstelling ook de diffusion map weergegeven (\ref{fig:CollaborativeDiffusionMap}). In deze voorstelling zijn lichtere kleuren plaatsen waar de ghost naartoe wil gaan terwijl donkere plaatsen vermeden worden.
Door het werken met aparte vensters per speler is het mogelijk om de verschillende vensters naast elkaar te zetten zodat het makkelijker is om verschillende spelers hun ontdekkingen te vergelijken. Ten slotte kunnen we via de GUI ook Pac-man bewegen, de nieuwe positie van Pac-man wordt dan via de RabbitMQ doorgestuurd naar iedereen in het kanaal. We hebben twee manieren om met pacman te bewegen, via de pijltjes kunnen we Pac-man continue laten bewegen. Door links of rechts ingedrukt te houden kunnen we hem laten draaien, het pijltje omhoog laat hem dan tegen een bepaalde snelheid vooruit rijden terwijl achteruit Pac-man achterwaarts doet rijden. Het is ook mogelijk om via de numpad toetsen per paneel te bewegen, 4, 8 ,6 ,2 laten pacman respectievelijk een paneel naar links omhoog, rechts of onder bewegen. Deze bewegingen worden gelimiteerd door muren en we zullen dus nooit met Pac-man door een muur kunnen rijden.

\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{SimulatorMaze.png}
\caption{Een screenshot van de simulatorview}
\label{fig:simulatorview}
\end{figure}
\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{ColorMapMaze.png}
\caption{Een screenshot van de colorMap van de simulator.}
\label{fig:colorMapMaze}
\end{figure}

\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{GhostOwnMaze.png}
\caption{Een screenshot van de eigen maze van een ghost.}
\label{fig:GhostOwnMaze}
\end{figure}

\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{CollaborativeDiffMap.png}
\caption{Een screenshot van de collaboratieveDiffusionMap van de robot.}
\label{fig:CollaborativeDiffusionMap}
\end{figure}

\subsection{Alternatieve Maze voorstellingen}
\label{sec: alternatieveMaze}

\subsubsection{HashMap}
De oorspronkelijke voorstelling van de maze was op basis van een hashmap.
Deze hashmap had als sleutel een stel co\"ordinaten en als waarde de sector die zich op deze co\"ordinaten bevindt.\\
Voordelen:
\begin{itemize}
 \item Effici\"ente opslag want er worden niet meer waarden bij gehouden dan nodig is voor de volledige maze weer te geven.
 \item Geen problemen als de robot in zijn eigen assenstelsel een negatieve richting uit gaat.
 \item Opzoeken van een bepaalde locatie is zeer effici\"ent
\end{itemize}
Nadelen:
\begin{itemize}
 \item Geen straightforward omzetting tussen de opslag van de maze en de voorstelling ervan.
 \item Berekenen van muren in een bepaalde richting kan niet effici\"ent gebeuren.
 \item Mogelijk inconsistenties: twee naburige sectoren kunnen het oneens zijn over de aanwezigheid van een scheidingsmuur.
\end{itemize}

\subsubsection{Twee-dimensionale array}
Hier geeft de maze alle sectoren weer op basis van zijn x- en y-coordinaat.\\
Voordelen:    
\begin{itemize}
 \item Zeer duidelijke link tussen het voorstellen van een maze en de opslag ervan.
\end{itemize}
Nadelen:
\begin{itemize}
 \item     Er moet teveel ruimte worden vrijgehouden om de volledige maze te kunnen weergeven.
    Dit is een probleem aangezien de robot niet op voorhand weet niet in welke richting hij moet bewegen.
 \item    Je kan niet een negatieve richting uit gaan in je assenstelsel.
\end{itemize}
Aangezien niet direct een oplossing werd gevonden voor het probleem van de negatieve indices en omdat het opslaan van een willekeurig grote doolhof ook niet voor de hand liggend is,
werd initieel gekozen voor de voorstelling met een HashMap.
Later is dan toch gekozen voor het uiteindelijke ontwerp. Een beschrijving van dit voorstel is te vinden in sectie \ref{sec: Spelwereld}.



\subsection{Test Infraroodsensor}
\label{sec: testIR}
Opdat we vlot met de infraroodsensor zouden kunnen werken is het van belang om zijn sterke en zwakke kanten te ontdekken.
Om te testen of de robot zich gedraagt zoals beschreven in de documentatie zijn er vier soorten tests uitgevoerd die elk een ander aspect van de sensor analyseren.
\subsubsection{Eerste test}
De eerste test is het detecteren van de infraroodbal, wanneer deze zich op een variabele afstand van de robot bevindt.
Dit is getest in drie verschillende richtingen (achteruit kan de sensor niet detecteren).
De bal is afwisselend voor, links en rechts van de robot gelegd en dan zijn de volgende maximale afstanden opgemeten:
\begin{itemize}
\item Vooruit: 8,10m
\item Rechts: 5,70m
\item Links: 2,20 m
\end{itemize}
\subsubsection{Tweede test}
De volgende test gaat na of het roteren van de infraroodbal effect heeft op de gedetecteerde afstand.
Om deze test uit te voeren wordt de robot net op de maximale afstand in een bepaalde richting geplaatst (in dit geval op 2,20m links van de robot).
Voor de test werd de bal om twee assen geroteerd: de as loodrecht omhoog (y-as) en de as loodrecht op de kijkrichting van de IRSensor en evenwijdig met de grond (x-as).
Volgende resultaten zijn bekomen:
\begin{itemize}
 \item Een rotatie rond de y-as heeft geen effect op de detectie van de robot.
 \item De rotatie rond de x-as heeft wel een effect bij de detectie.
\end{itemize}
Dit verschil is te verklaren doordat de infraroodzenders enkel in het horizontale vlak symmetrisch gepositioneerd zijn.

\subsubsection{Derde test}
De derde test controleert de nauwkeurigheid van de sectorbepaling (hierbij stellen de verschillende sectoren de richting vanwaar de infraroodsensor Pac-man meent te zien).
De infraroodsensor definieert de sectoren van 1-9 gespreid over een hoek van -120 tot 120 graden. Voor deze test is de bal op een afstand van 80cm t.o.v. de robot gelegd.
Hierbij nemen we de hoek positief wanneer de robot naar rechts roteert en anders negatief.
In deze test is het de bedoeling te testen of de overgang van de ene naar de sector overeenkomt met wat gedefinieerd wordt in de documentatie over de infraroodsensor.
\begin{tabular}{| c | c | c |}
 \hline
 Overgang sector & Gemeten (graden) & Specificatie (graden) \\
 \hline \hline
 5 $\rightarrow$ 4 & 26 & 13.33 \\
 4 $\rightarrow$ 3 & 36 & 40 \\
 3 $\rightarrow$ 2 & 71 & 60.66 \\
 \hline
 2 $\rightarrow$ 1 & 90 & 93.33 \\
 1 $\rightarrow$ 0 & 141 & 120 \\
 5 $\rightarrow$ 6 & -25 & -13.33\\
 6 $\rightarrow$ 7 & -34 & -40 \\
 7 $\rightarrow$ 8 & -71 & -60.66 \\
 \hline
 8 $\rightarrow$ 9 & -84 & -93.33 \\
 9 $\rightarrow$ 0 & -140 & -120 \\
 \hline
\end{tabular}

\begin{figure}[ht]
 \centering
 \includegraphics[width=\linewidth]{nauwkeurigheidIR.png}
 \caption{De relatieve afwijking ten opzichte van de exacte waarde.}
 \label{fig:afwijking}
\end{figure}

Hierbij is te zien dat vooral de randsectoren en recht voor de robot een veel groter interval worden weergegeven dan gedocumenteerd.
De andere sectoren worden redelijk nauwkeurig weergegeven.
Voor deze test is de gemiddelde afwijking gelijk aan 10,07 graden en de standaarddeviatie hier is gelijk aan 6.69 graden.

\subsubsection{Vierde test}
Deze laatste test controleert het gedrag van de infraroodsensor in het doolhof.
In deze test wordt de robot voor een muur geplaatst met daarachter de infraroodbal.
Het doolhof is zo gecre\"eerd dat er een opening is van de robot tot de infraroodbal.
Tijdens de test valt op dat via weerkaatsing op de muur de infraroodsensor toch gedetecteerd wordt.
In dit geval detecteert de sensor \emph{Pac-man} in sector drie. Dit zou niet mogelijk mogen zijn.
Op deze manier kan je niet zeker zijn dat \emph{Pac-man} zich in een rechte lijn voor de robot bevindt wanneer de IRseeker hem detecteert.
Dit geeft een belangrijk probleem weer waarmee tijdens de demo zeker rekening moet worden gehouden.
\begin{figure}[ht]
 \centering
 \includegraphics[scale=0.5]{infraroodTest.jpg}
 \caption{Test van de infraroodsensor in het doolhof.}
 \label{fig:testIR}
\end{figure}

\subsection{Test UltrasonicSensor}
\label{sec: testUltrasone}
Om de werkelijkheid nauwkeurig te kunnen representeren in de simulator zijn er gegevens nodig omtrend de nauwkeurigheid van de ultrasonesensor.  Op basis hiervan kan de ultrasone sensor waarheidsgetrouw voorgesteld worden in de simulator en kan de betrouwbaarheid van de sensor geanaliseerd worden. \\
De nauwkeurigheid van de sensor wordt berekend op basis van een simpele test die de gemeten waarde tot een muur vergeleken wordt met de waarde die de ultrasone sensor weergeeft.  Wanneer we dit voor verschillende afstanden doen bekom je volgende grafiek.
\begin{figure}[ht]
 \centering
 \includegraphics[scale=0.37]{UltrasoneSensorAfbeelding.png}
 \caption{De afwijking van de ultrasone sensor tov de effectieve afstand tot de muur.}
 \label{fig:testUltraSone}
\end{figure}

Hierbij is te zien dat de afwijking van de sensor gering is. De standaardafwijking bedraagt 0.977 met een gemiddelde van 0.792.

\subsection{Test motoren}
\label{sec: testMotoren}
Dit onderdeel is een kopie van het verslag uit het eerste semester. Hierin zijn enkel de relevante testen overgehouden en de conclusies behouden.  
De robot beschikt over een kalibratieprogramma dat ontwikkeld werd om de nauwkeurigheid van het rijgedrag te verbeteren. Dit programma bestaat uit twee delen: een test die de robot tien keer om zijn as laat draaien en een test die de robot drie meter vooruit laat rijden.
De afwijking kan ingevoerd worden in het programma waarna dit de juiste wielbasis en wieldiameter berekent. Deze waarden worden gebruikt in alle andere programma's zodat hun nauwkeurigheid gegarandeerd wordt.
Op deze manier kan het design van de robot gemakkelijk aangepast worden zonder alle nieuwe waarden handmatig in te moeten geven.
Om de nauwkeurigheid van de robot en de effectiviteit van het kalibreren na te gaan, werden drie soorten tests uitgevoerd waarbij telkens de afwijking werd gemeten en geanalyseerd. Hieronder staan de resultaten van de 2 relevante metingen voor dit verslag.
Voor meer uitleg en achtergrond kan je altijd gaan naar het eindverslag van het eerste semester.
\begin{enumerate}
    \item De robot rijdt 3 meter rechtdoor en de afwijking in de lengte wordt gemeten.
    \begin{figure}[ht]
    \centering
    \includegraphics[scale=0.4]{afwijkingMotor.jpg}
    \caption{De afwijking in de lengte van de motoren bij het rijden van 3m afstand}
    \label{fig:testMotoren}
    \end{figure}
    De gemiddelde afwijking bij deze test is 1,2 mm en de standaarddeviatie bedraagt 1,81 mm.
    In het ideale geval zou het gemiddelde 0 mm moeten zijn. Dat dit niet zo is komt door de meetnauwkeurigheid en de testwijze.
\item De robot draait 3600 graden om zijn as en het verschil in begin- en eindori\"entatie wordt gemeten.
    \begin{figure}[ht]
    \centering
    \includegraphics[scale=0.4]{afwijkingMotorRotatie.jpg}0
    \caption{De afwijking van de motor bij het roteren.}
    \label{fig:testMotorRotatie}
    \end{figure}
    De gemiddelde afwijking bedraagt -0,05 graden en de standaarddeviatie is 6,24 graden (of 0,62 graden per volledige omwenteling).
    De robot heeft dus gemiddeld gezien geen afwijkingen in het draaien.
\end{enumerate}

\subsection{Samenwerking team}
\label{sec: samenwerking}
In dit deel wordt er uitgelegd hoe er is omgegaan met het feit dat Harm tijdens onze P\&O sessie een andere les heeft.
Hierdoor is Harm niet in staat om het laatste uur van de verplichte sessie te kunnen volgen.  
Om hiermee om te gaan zijn er enkele afspraken gemaakt om zo de samenwerking in groep te vergemakkelijken.  
Ten eerste is er afgesproken dat Harm dat uur inhaalt in een moment waarbij het voor hem het gemakkelijkste is.
Dit is meestal op dinsdagvoormiddag aangezien hij dan geen les heeft en zo toch snel die achterstand wegwerkt.
Aangezien hij door dit voortijdig weggaan ook steeds de eindvergadering mist is er afgesproken dat hij regelmatig een update stuurt via mail omtrent zijn vooruitgang.
Hij kan ook steeds de vooruitgang van de andere leden volgen door het verslag van de sessie te lezen.
Op deze manier wordt er toch een poging gedaan om genoeg contact te houden, zodat iedereen weet waar de rest mee bezig is.

\end{document}